package com.platform.qujia.service.impl;


import com.platform.qujia.constantEnum.Constant;
import com.platform.qujia.dao.*;
import com.platform.qujia.enums.CardRecordType;
import com.platform.qujia.enums.ElectronCardType;
import com.platform.qujia.param.request.RechargeBalance;
import com.platform.qujia.pojo.*;
import com.platform.qujia.service.EnterpriseService;
import com.platform.qujia.service.IUserVirtualGradeRelService;
import com.platform.qujia.service.ReductionActivityBalanceRecordService;
import com.platform.qujia.service.ReductionActivityService;
import com.platform.qujia.utils.exception.CustomException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * (ReductionActivityBalanceRecord)表服务实现类
 *
 * @author makejava
 * @since 2023-08-29 17:24:01
 */
@Service("reductionActivityBalanceRecordService")
public class ReductionActivityBalanceRecordServiceImpl implements ReductionActivityBalanceRecordService {

    private static final Logger log = LoggerFactory.getLogger(ReductionActivityBalanceRecordServiceImpl.class);

    @Resource
    private ReductionActivityBalanceRecordMapper reductionActivityBalanceRecordMapper;
    @Resource
    private ReductionActivityMapper reductionActivityMapper;
    @Resource
    private ReductionOilRelationsMapper reductionOilRelationsMapper;
    @Resource
    private ReductionRulesMapper reductionRulesMapper;
    @Resource
    private EnterpriseService enterpriseService;
    @Resource
    private AppUserInfoMapper appUserInfoMapper;
    @Autowired
    private ReductionActivityService reductionActivityService;
    @Resource
    private CustomerCardUseRecordMapper customerCardUseRecordMapper;
    @Autowired
    private GradeMapper gradeMapper;
    @Autowired
    private AppUserSuperDetailMapper appUserSuperDetailMapper;
    @Autowired
    private AppUserSuperMapper appUserSuperMapper;

    @Autowired
    private PhysicalCardMapper physicalCardMapper;
    @Autowired
    private IUserVirtualGradeRelService userVirtualGradeRelService;

    /**
     * 通过ID查询单条数据
     *
     * @param rabrId 主键
     * @return 实例对象
     */
    @Override
    public ReductionActivityBalanceRecord queryById(Long rabrId) {
        return this.reductionActivityBalanceRecordMapper.queryById(rabrId);
    }

    /**
     * 分页查询
     *
     * @param reductionActivityBalanceRecord 筛选条件
     * @param pageRequest      分页对象
     * @return 查询结果
     */
    @Override
    public Page<ReductionActivityBalanceRecord> queryByPage(ReductionActivityBalanceRecord reductionActivityBalanceRecord, PageRequest pageRequest) {
        long total = this.reductionActivityBalanceRecordMapper.count(reductionActivityBalanceRecord);
        return new PageImpl<>(this.reductionActivityBalanceRecordMapper.queryAllByLimit(reductionActivityBalanceRecord, pageRequest), pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param reductionActivityBalanceRecord 实例对象
     * @return 实例对象
     */
    @Override
    public ReductionActivityBalanceRecord insert(ReductionActivityBalanceRecord reductionActivityBalanceRecord) {
        this.reductionActivityBalanceRecordMapper.insert(reductionActivityBalanceRecord);
        return reductionActivityBalanceRecord;
    }

    /**
     * 修改数据
     *
     * @param reductionActivityBalanceRecord 实例对象
     * @return 实例对象
     */
    @Override
    public ReductionActivityBalanceRecord update(ReductionActivityBalanceRecord reductionActivityBalanceRecord) {
        this.reductionActivityBalanceRecordMapper.update(reductionActivityBalanceRecord);
        return this.queryById(reductionActivityBalanceRecord.getRabrId());
    }

    /**
     * 通过主键删除数据
     *
     * @param rabrId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long rabrId) {
        return this.reductionActivityBalanceRecordMapper.deleteById(rabrId) > 0;
    }

    @Override
    public Integer createBalanceRecord(String orderNo,String CardOilsType,BigDecimal amt, Station station,Long userId,String mobilePhone,Enterprise enterprise,String paymentMethod) {
        if (StringUtils.isBlank(mobilePhone)) {
            log.info("手机号为空");
            return 0;
        }
        //当前是否存在满减活动
        AppUserInfo appUserInfo=new AppUserInfo();
        appUserInfo.setMobilePhone(mobilePhone);
        appUserInfo.setStationId(enterprise.getEnterpriseId());
        List<AppUserInfo> appUserInfos = appUserInfoMapper.selectAppUserInfoByMobilePhoneAndStationId(appUserInfo);
        AppUserInfo userInfo = null;
        if(appUserInfos.size()>0){
            userInfo = appUserInfos.get(0);
        }
        String memberCategory = null;
        if (userInfo != null && StringUtils.isBlank(userInfo.getMemberLevel())) {
            String userGrade = "0";
            UserVirtualGradeRel virtualGradeRel = userVirtualGradeRelService.queryUserVirtualGrade(Long.valueOf(enterprise.getEnterpriseId()),
                    Long.valueOf(userInfo.getUserId()), LocalDateTime.now());
            if (virtualGradeRel != null) {
                userGrade = virtualGradeRel.getGradeCode();
            }else{
                Grade grade = new Grade();
                grade.setGradeGrowValue(userInfo.getGrowUpValue());
                grade.setEnterpriseId(Long.valueOf(enterprise.getEnterpriseId()));
                grade.setDeleteFlag("0");
                List<Grade> grades = gradeMapper.selectUserGrade(grade);
                //log.info("grades===={}",grades);
                if(grades != null && grades.size() == 1){
                    if(grades.get(0).getGradeCode() != null) userGrade = grades.get(0).getGradeCode();
                }
            }
            userInfo.setMemberLevel(userGrade);
            // 判断是不是超级会员
            Date now = new Date();
            List<AppUserSuperDetail> appUserSuperDetails = appUserSuperDetailMapper.selectAppUserSuperDetailList(AppUserSuperDetail.builder()
                    .enterpriseId(Long.valueOf(enterprise.getEnterpriseId()))
                    .userId(Long.valueOf(userInfo.getUserId()))
                    .beginDate(now)
                    .endDate(now)
                    .build());
            if(appUserSuperDetails != null && appUserSuperDetails.size() == 1){
                //有记录，是超级会员
                AppUserSuper appUserSuper = appUserSuperMapper.selectAppUserSuperById(appUserSuperDetails.get(0).getSuperId());
                if (appUserSuper != null) {
                    userInfo.setSuperUser(ReductionActivityServiceImpl.MEMBER_LEVEL_MAP.get(appUserSuper.getSuperName()));
                }
                //appUserInfos.setSuperUser(Constant.MEMBER_LEVEL_SUPER);
            }else{
                // 不是
                userInfo.setSuperUser(null);
            }
            CustomerCardUseRecord record = new CustomerCardUseRecord();
            record.setMobilePhone(userInfo.getMobilePhone());
            record.setEnterpriseId(enterprise.getEnterpriseId());
            if (!StringUtils.equals("1",enterprise.getCardUseRangeFlag())) {
                record.setStationId(station.getStationId());
            }
            record.setUsageType("+");
            record.setStatus("1");
            ArrayList<String> pts = new ArrayList<>(2);
            pts.add(CardRecordType.MANUAL_ADD.getKey());
            pts.add(CardRecordType.WX_RECHARGE.getKey());
            Integer c = customerCardUseRecordMapper.countByExampleAndPayTypes(record, pts);
            if (c == null || c < 2) {
                memberCategory = Constant.MEMBER_CATEGORY_NEW_USER;
            }else{
                memberCategory = Constant.MEMBER_CATEGORY_OLD_USER;
            }
            // 更新用户标识
            ReductionActivityBalanceRecord example = new ReductionActivityBalanceRecord();
            if (StringUtils.equals("1",enterprise.getCardUseRangeFlag())) {
                example.setEnterpriseId(enterprise.getEnterpriseId().longValue());
            }else{
                example.setStationId(station.getStationId().longValue());
            }
            example.setMobilePhone(mobilePhone);
            reductionActivityBalanceRecordMapper.updateNewUserFlagByPhoneAndEnterpriseId(example,memberCategory);
        }

        ReductionActivity reductionActivity=new ReductionActivity();
        reductionActivity.setActivityUse(ReductionActivityBalanceRecord.activityType_RCH);
        reductionActivity.setEnterpriseId(station.getEnterpriseId().longValue());
        reductionActivity.setCurrentDate(new Date());
        if (userInfo != null) {
            reductionActivity.setMemberLevel(userInfo.getMemberLevel());
            reductionActivity.setSuperUser(userInfo.getSuperUser());
            reductionActivity.setMemberCategory(memberCategory);
        }
        reductionActivity.setPaymentMethod(paymentMethod);
        reductionActivity.setActivityEnabled("1");
        LocalDate localDate = LocalDate.now();
        int week = localDate.getDayOfWeek().getValue();
        int month = localDate.getDayOfMonth();
        reductionActivity.setWeek(String.valueOf(week));
        reductionActivity.setMonth(String.valueOf(month));
        reductionActivity.setStationId(station.getStationId().longValue());
        String key="";
        String key2="";
        if(CardOilsType.equals(ReductionActivityBalanceRecord.card_oils_type_gasoline)){
            //如果充值的是汽油
            key="汽油";
        }
        if(CardOilsType.equals(ReductionActivityBalanceRecord.card_oils_type_diesel)){
            key="柴油";
        }
        if(CardOilsType.equals(ElectronCardType.LNG.getKey())){
            key="LNG";
            key2="天然气";
            reductionActivity.setOilClass2("天然气");
        }
        if(CardOilsType.equals(ElectronCardType.CNG.getKey())){
            key="CNG";
        }
        reductionActivity.setOilClass(key);
        reductionActivity.setRechargeActivityRechargeEnable(1);
        List<ReductionActivity> reductionActivities = reductionActivityMapper.selectReductionActivityList(reductionActivity);
        reductionActivities=reductionActivityService.checkLabelUser(reductionActivities,mobilePhone,enterprise.getEnterpriseId().longValue());
        // 充值的时候判断，计算立减优惠不判断时间
        LocalTime now = LocalTime.now();
//        if (!reductionActivityService.checkDayTime(activity,week,month, now)) {
//            return 0;
//        }
        if (reductionActivities == null || reductionActivities.isEmpty()) {
            return 0;
        }
        reductionActivities = reductionActivities.stream().filter((r) -> reductionActivityService.checkDayTime(r, week, month, now)).collect(Collectors.toList());
        reductionActivity.setCreateTime(new Date());
        if(reductionActivities.size()>0) {
            ReductionActivity activity = reductionActivities.get(0);
            ReductionOilRelations reductionOilRelations=new ReductionOilRelations();
            reductionOilRelations.setActivityId(activity.getActivityId());

            // 充值的时候判断，计算立减优惠不判断时间
//            LocalDate localDate = LocalDate.now();
//            int week = localDate.getDayOfWeek().getValue();
//            int month = localDate.getDayOfMonth();
//            LocalTime now = LocalTime.now();
//            if (!reductionActivityService.checkDayTime(activity,week,month, now)) {
//                return 0;
//            }

            List<ReductionOilRelations> list=reductionOilRelationsMapper.query(reductionOilRelations);
            Map<String, List<ReductionOilRelations>> collect = list.stream().collect(Collectors.groupingBy(ReductionOilRelations::getOilClass));

            for (ReductionOilRelations oilRelations : list) {
                ReductionRules rulesQuery=new ReductionRules();
                rulesQuery.setActivityOilId(oilRelations.getActivityOilId());
                List<ReductionRules> rules=reductionRulesMapper.query(rulesQuery);
                oilRelations.setRules(rules);
            }

            boolean isGeneric = StringUtils.equals(ElectronCardType.GENERIC.getKey(), CardOilsType);
            // 是否通用卡
            if(collect.get(key)!=null || collect.get(key2) != null || isGeneric){
                BigDecimal rechargeAmt = amt; // 最后一次充值金额门槛
                if (!isGeneric) {
                    // 非通用卡，判断充值的时候是否满足设置的门槛
                    List<ReductionRules> totalRules=new ArrayList<>();
                    List<ReductionOilRelations> oilRelations = collect.get(key) != null ? collect.get(key) : collect.get(key2);
                    for (ReductionOilRelations oilRelation : oilRelations) {
                        totalRules.addAll(oilRelation.getRules());
                    }
                    //只要达到门槛就算作立减活动内的优惠金额
                    boolean check=false;
                    for (ReductionRules totalRule : totalRules) {
                        if(totalRule.getFull()<=amt.doubleValue()){
                            check=true;
                            break;
                        }
                    }
                    //充值金额
                    if(!check){
                        //未达到门槛
                        amt=BigDecimal.ZERO;
                    }
                }
                // 通用卡不判断门槛，直接加余额，消费的时候再根据油品判断门槛

                //如果存在充值满减活动记录余额
                ReductionActivityBalanceRecord balanceRecord=new ReductionActivityBalanceRecord();
                //balanceRecord.setUserId(userId);
                if (StringUtils.equals("1",enterprise.getCardUseRangeFlag())) {
                    balanceRecord.setEnterpriseId(station.getEnterpriseId().longValue());
                }else{
                    balanceRecord.setStationId(station.getStationId().longValue());
                }
                balanceRecord.setCardOilsType(CardOilsType);
                balanceRecord.setMobilePhone(mobilePhone);
                List<ReductionActivityBalanceRecord> records=reductionActivityBalanceRecordMapper.query(balanceRecord);
                int r;
                if(records.size()>0){
                    ReductionActivityBalanceRecord activityBalanceRecord = records.get(0);
                    //记录上一次的充值金额
                    if(StringUtils.isNotEmpty(orderNo)){
                        customerCardUseRecordMapper.updateLastRechargeAmtByNo(activityBalanceRecord.getRechargeAmt(),orderNo);
                    }


                    BigDecimal balance = activityBalanceRecord.getBalance().add(amt);
                    //如果之前有记录，更新余额
                    balanceRecord.setBalance(balance);
                    balanceRecord.setRechargeAmt(rechargeAmt);
                    balanceRecord.setRabrId(activityBalanceRecord.getRabrId());
                    balanceRecord.setUpdateTime(new Date());
                    r = reductionActivityBalanceRecordMapper.update(balanceRecord);
                }else{
                    //如果之前没记录
                    balanceRecord.setBalance(amt);
                    balanceRecord.setRechargeAmt(rechargeAmt);
                    balanceRecord.setNewUserFlag(memberCategory);
                    r = reductionActivityBalanceRecordMapper.insert(balanceRecord);
                }
                return r;
            }
        }
        return 0;
    }

    @Override
    public Integer createBalanceRecord(BigDecimal amt, String physicalCardNo,Long enterpriseId,String paymentMethod,Long stationId) {
        if(StringUtils.isEmpty(physicalCardNo)){
            throw new CustomException("卡号不能为空");
        }
        PhysicalCard physicalCard = physicalCardMapper.selectByPhysicalCardNo(physicalCardNo);
        Integer i =0;
        if(physicalCard==null){
            return 0;
        }
        ReductionActivity reductionActivity=new ReductionActivity();
        reductionActivity.setActivityUse(ReductionActivityBalanceRecord.activityType_RCH);
        reductionActivity.setEnterpriseId(enterpriseId);
        reductionActivity.setCurrentDate(new Date());

        reductionActivity.setPaymentMethod(paymentMethod);
        reductionActivity.setActivityEnabled("1");
        LocalDate localDate = LocalDate.now();
        int week = localDate.getDayOfWeek().getValue();
        int month = localDate.getDayOfMonth();
        reductionActivity.setWeek(String.valueOf(week));
        reductionActivity.setMonth(String.valueOf(month));
        reductionActivity.setStationId(stationId);
        String key="";
        String CardOilsType=physicalCard.getCardType();
        if(CardOilsType.equals(ReductionActivityBalanceRecord.card_oils_type_gasoline)){
            //如果充值的是汽油
            key="汽油";
        }
        if(CardOilsType.equals(ReductionActivityBalanceRecord.card_oils_type_diesel)){
            key="柴油";
        }
        reductionActivity.setOilClass(key);
        reductionActivity.setPhysicalCardType(physicalCard.getCardType());
        List<ReductionActivity> reductionActivities = reductionActivityMapper.selectReductionActivityList(reductionActivity);

        LocalTime now = LocalTime.now();
//        if (!reductionActivityService.checkDayTime(activity,week,month, now)) {
//            return 0;
//        }
        if (reductionActivities == null || reductionActivities.isEmpty()) {
            return 0;
        }
        reductionActivities = reductionActivities.stream().filter((r) -> reductionActivityService.checkDayTime(r, week, month, now)).collect(Collectors.toList());

        if(reductionActivities.size()>0) {
            ReductionActivity activity = reductionActivities.get(0);
            ReductionOilRelations reductionOilRelations=new ReductionOilRelations();
            reductionOilRelations.setActivityId(activity.getActivityId());

            List<ReductionOilRelations> list=reductionOilRelationsMapper.query(reductionOilRelations);
            Map<String, List<ReductionOilRelations>> collect = list.stream().collect(Collectors.groupingBy(ReductionOilRelations::getOilClass));

            for (ReductionOilRelations oilRelations : list) {
                ReductionRules rulesQuery=new ReductionRules();
                rulesQuery.setActivityOilId(oilRelations.getActivityOilId());
                List<ReductionRules> rules=reductionRulesMapper.query(rulesQuery);
                oilRelations.setRules(rules);
            }

            if(physicalCard.getCardType().equals("1")){
                //如果充值的是汽油
                key="汽油";
            }
            if(physicalCard.getCardType().equals("2")){
                key="柴油";
            }
            if(physicalCard.getCardType().equals("3")){
                key="LNG";
            }
            if(physicalCard.getCardType().equals("4")){
                key="CNG";
            }
            boolean isGeneric = StringUtils.equals(ElectronCardType.GENERIC.getKey(), physicalCard.getCardType());
            // 是否通用卡
            if(collect.get(key)!=null || isGeneric){
                BigDecimal rechargeAmt = amt; // 最后一次充值金额门槛
                if (!isGeneric) {
                    // 非通用卡，判断充值的时候是否满足设置的门槛
                    List<ReductionRules> totalRules=new ArrayList<>();
                    List<ReductionOilRelations> oilRelations = collect.get(key);
                    for (ReductionOilRelations oilRelation : oilRelations) {
                        totalRules.addAll(oilRelation.getRules());
                    }
                    //只要达到门槛就算作立减活动内的优惠金额
                    boolean check=false;
                    for (ReductionRules totalRule : totalRules) {
                        if(totalRule.getFull()<=amt.doubleValue()){
                            check=true;
                            break;
                        }
                    }
                    //充值金额
                    if(!check){
                        //未达到门槛
                        amt=BigDecimal.ZERO;
                    }
                }
                ReductionActivityBalanceRecord record = new ReductionActivityBalanceRecord();
                record.setPhysicalCardNo(physicalCardNo);
                List<ReductionActivityBalanceRecord> query = reductionActivityBalanceRecordMapper.query(record);
                if(query.size()>0){
                    ReductionActivityBalanceRecord balanceRecord = query.get(0);
                    balanceRecord.setRechargeAmt(amt);
                    BigDecimal balance = balanceRecord.getBalance();
                    if(balance==null) {
                        balance = BigDecimal.ZERO;
                    }
                    balanceRecord.setBalance(balance.add(amt));
                    i = reductionActivityBalanceRecordMapper.update(balanceRecord);
                }else{
                    record.setBalance(amt);
                    record.setRechargeAmt(amt);
                    i = reductionActivityBalanceRecordMapper.insert(record);
                }
            }
        }
        return i;
    }

    @Override
    public List<ReductionActivityBalanceRecord> query(ReductionActivityBalanceRecord recordQuery) {
        return reductionActivityBalanceRecordMapper.query(recordQuery);
    }

    @Override
    public Integer updateBalance(String cardOilsType, Long userId,Long stationId, Long enterpriseId, BigDecimal rechargeDiscountAmt, BigDecimal orderAmt,String mobilePhone){
        if(rechargeDiscountAmt == null || rechargeDiscountAmt.compareTo(BigDecimal.ZERO) <=0){
            return 0;
        }
        return this.updateBalance(cardOilsType,userId,stationId,enterpriseId,orderAmt,mobilePhone);
    }

    @Override
    public Integer updateBalance(String cardOilsType, Long userId,Long stationId, Long enterpriseId, BigDecimal amt,String mobilePhone) {
        if (amt==null || amt.compareTo(BigDecimal.ZERO)<=0) {
            return 0;
        }
        ReductionActivityBalanceRecord recordQuery=new ReductionActivityBalanceRecord();
        //recordQuery.setUserId(userId);
        recordQuery.setCardOilsType(cardOilsType);
        recordQuery.setMobilePhone(mobilePhone);

        Enterprise enterprise = enterpriseService.selectEnterpriseInfo(enterpriseId.intValue());
        if (StringUtils.equals("1",enterprise.getCardUseRangeFlag())) {
            recordQuery.setEnterpriseId(enterpriseId);
        }else{
            recordQuery.setStationId(stationId);
        }
        List<ReductionActivityBalanceRecord> query = reductionActivityBalanceRecordMapper.query(recordQuery);
        if(query.size()>0){
            ReductionActivityBalanceRecord activityBalanceRecord = query.get(0);
            activityBalanceRecord.setUpdateTime(new Date());
            if(activityBalanceRecord.getBalance().subtract(amt).compareTo(BigDecimal.ZERO)==-1){
                activityBalanceRecord.setBalance(BigDecimal.ZERO);
            }else{
                activityBalanceRecord.setBalance(activityBalanceRecord.getBalance().subtract(amt));
            }
            return reductionActivityBalanceRecordMapper.update(activityBalanceRecord);
        }
        return 0;
    }

    @Override
    public Integer updateBalance( BigDecimal amt,BigDecimal rCHReductionAmt,String physicalCardNo) {
        if (amt==null || amt.compareTo(BigDecimal.ZERO)<=0) {
            return 0;
        }
        if (rCHReductionAmt==null || rCHReductionAmt.compareTo(BigDecimal.ZERO)<=0) {
            return 0;
        }
        ReductionActivityBalanceRecord recordQuery=new ReductionActivityBalanceRecord();
        recordQuery.setPhysicalCardNo(physicalCardNo);


        List<ReductionActivityBalanceRecord> query = reductionActivityBalanceRecordMapper.query(recordQuery);
        if(query.size()>0){
            ReductionActivityBalanceRecord activityBalanceRecord = query.get(0);
            activityBalanceRecord.setUpdateTime(new Date());
            if(activityBalanceRecord.getBalance().subtract(amt).compareTo(BigDecimal.ZERO)==-1){
                activityBalanceRecord.setBalance(BigDecimal.ZERO);
            }else{
                activityBalanceRecord.setBalance(activityBalanceRecord.getBalance().subtract(amt));
            }
            return reductionActivityBalanceRecordMapper.update(activityBalanceRecord);
        }
        return 0;
    }
}
